home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / vol11n06.zip / PCUNZP.ASM < prev    next >
Assembly Source File  |  1992-01-27  |  59KB  |  1,918 lines

  1. comment ~
  2.  
  3.                Deziper
  4.  
  5. ~
  6. _TEXT          SEGMENT PUBLIC 'CODE'
  7.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  8.                ORG     100H
  9. START:         JMP     MAIN
  10.  
  11.  
  12. ;              DATA AREA
  13. ;              ---------
  14.                DB      CR,SPACE,SPACE,SPACE,CR,LF
  15.  
  16. COPYRIGHT      DB      "PCUNZIP 1.0 Copyright (c) 1992 Michael J. Mefford",CR,LF
  17. FIRST_RIGHTS   DB      "First Published in PC Magazine, March 31, 1992",CR,LF,LF
  18.  
  19. SYNTAX         DB      "Syntax: PCUNZIP filename [\path] [/v] [/e] [/o] [/?]",CR,LF,LF
  20.  
  21.                DB      "/e filespec   = extract specific file",CR,LF
  22.                DB      "/v [filespec] = view zipped files",CR,LF
  23.                DB      "/o            = overwrite any existing files",CR,LF,LF
  24.  
  25.                DB      "Putting a filename after /e will extract a specific; required",CR,LF
  26.                DB      "Putting a filename after /v will list a specific file",CR,LF,LF,"$"
  27.  
  28. CR             =       13
  29. LF             =       10
  30. CTRL_Z         =       26
  31. SPACE          =       32
  32. BELL           =       7
  33. Y_SCAN         =       15H
  34. N_SCAN         =       31H
  35. TRUE           =       1
  36. FALSE          =       0
  37.  
  38. KILOBYTES      =       1024
  39. PARAGRAPH      =       16
  40.  
  41. DTA            =       80H
  42.  
  43. MATCHING       STRUC
  44. RESERVED       DB      21 DUP (?)
  45. ATTR           DB              ?
  46.                DW              ?
  47.                DW              ?
  48.                DW              ?
  49.                DW              ?
  50. FILE_NAME      DB      13 DUP (?)
  51. MATCHING       ENDS
  52.  
  53. LOCAL_HEADER    STRUC
  54. SIGNATURE       DB     "PK",3,4
  55. EXTRACT_VER     DW     ?
  56. BIT_FLAG        DW     ?
  57. ZIP_TYPE        DW     ?
  58. FILE_TIME       DW     ?
  59. FILE_DATE       DW     ?
  60. CRC_32          DW     ?,?
  61. COMPRESS_SIZE   DW     ?,?
  62. UNCOMPRESS_SIZE DW     ?,?
  63. FILENAME_LEN    DW     ?
  64. EXTRA_FIELD_LEN DW     ?
  65. LOCAL_HEADER    ENDS
  66.  
  67. LOCAL_SIG      DB      "PK",3,4
  68. CENTRAL_SIG    DB      "PK",1,2
  69.  
  70. ;Unshrink stuff
  71.  
  72. MIN_CODE_SIZE  =       9
  73. MAX_CODE_SIZE  =       13
  74. SPECIAL_CODE   =       256
  75. FIRST_FREE     =       257
  76. TRIE_SIZE      =       (1 SHL MAX_CODE_SIZE) + 1
  77. FREE           =       -1
  78.  
  79. PREFIX_SIZE    =       TRIE_SIZE * 2    ;Word
  80. SUFFIX_SIZE    =       TRIE_SIZE * 2    ;Char + void
  81. READ_SIZE      =       127 * 512
  82. WRITE_SIZE     =       127 * 512
  83. DIR_SIZE       =       66
  84. LOCAL_STACK    =       512
  85. PREFIX_P       =       PREFIX_SIZE / PARAGRAPH
  86. SUFFIX_P       =       SUFFIX_SIZE / PARAGRAPH
  87. READ_P         =       READ_SIZE / PARAGRAPH
  88. WRITE_P        =       WRITE_SIZE / PARAGRAPH
  89.  
  90. ;Explode stuff
  91.  
  92. SF_TREE        STRUC
  93. BIT_LENGTH     DB      ?
  94. VALUE          DB      ?
  95. TREE_CODE      DW      ?
  96. SF_TREE        ENDS
  97.  
  98. LIT_TREE_SIZE  =       256 * SIZE SF_TREE
  99. LEN_TREE_SIZE  =        64 * SIZE SF_TREE
  100. DIST_TREE_SIZE =        64 * SIZE SF_TREE
  101. TREE_ENTRIES   =        - 2
  102.  
  103. ;Expand stuff
  104.  
  105. FOLLOWER       STRUC
  106. SET_LEN        DB      ?
  107. SET            DB      32 DUP (?)
  108. PAD            DB      ?
  109. FOLLOWER       ENDS
  110.  
  111.  
  112. READ_SEG       DW      ?
  113. WRITE_SEG      DW      ?
  114.  
  115. DIR_LEN        =       65
  116. NAME_LEN       =       12
  117. ZIP_LEN        =       DIR_LEN + NAME_LEN
  118. OUTFILE        DB      NAME_LEN DUP (?), 0
  119. ZIP_NAME       DB      ZIP_LEN DUP (?), 0
  120. DIR_NAME       DB      ZIP_LEN DUP (?), 0
  121. SPECIFIC_NAME  DB      NAME_LEN DUP (?), 0
  122. VIEW_NAME      DB      39 DUP (?)
  123.                DB      CR,LF,"$"
  124.  
  125.  
  126. SEARCH_LEN     DW      ZIP_LEN
  127. SEARCH_NAME    DW      ZIP_NAME
  128.  
  129. FREE_NODE      DW      FIRST_FREE * 2
  130. EXTRACTOR      DW      ?
  131. RUNNING_CRC_32 DW      ?,?
  132.  
  133. BITS_LEFT      DB      ?
  134. CODE_BITS      DB      ?
  135. SAVE_BYTE      DB      ?
  136.  
  137. ATTRIBUTE      DB      ?
  138. SPIN_CNT       DB      0
  139. SPIN_INDEX     DW      0
  140. SPINNERS       DB      "/|\"
  141.  
  142. SPECIFIC_FLAG  DB      FALSE                   ;=TRUE if extract individual file.
  143. VIEW_FLAG      DB      FALSE                   ;=TRUE if view zipped files.
  144. EXTRACTED_FLAG DB      FALSE                   ;=TRUE if a file was extracted.
  145. OVERWRITE_FLAG DB      FALSE                   ;=TRUE if overwrite existing.
  146.  
  147. ZIP_EXT        DB      ".ZIP"
  148. MEMORY_MSG     DB      "Not enough memory"
  149. CR_LF_LF       DB      LF
  150. CR_LF          DB      CR,LF,"$"
  151. ZIP_MSG        DB      "Zip header not found$"
  152. FAILED_MSG     DB      "Extracted file maybe corrupt",BELL,"$"
  153. DISK_MSG       DB      "Not enough free disk space to extract file$"
  154. ENCRYPTED_MSG  DB      "File is encrypted$"
  155. NOT_FOUND_MSG  DB      "File not found$"
  156. EXISTS_MSG     DB      " already exists.  Overwrite  (Y/N)?$"
  157. UNKNOWN_MSG    DB      "Unknown compression method$"
  158. INVALID_MSG    DB      "Invalid drive$"
  159. DIR_MSG        DB      "Invalid target directory$"
  160. SYNTAX_MSG     DB      "Syntax error$"
  161.  
  162. ;              CODE AREA
  163. ;              ---------
  164. MAIN           PROC    NEAR
  165.  
  166.                CLD
  167.  
  168.                XOR     BH,BH
  169.                MOV     AH,8
  170.                INT     10H
  171.                MOV     ATTRIBUTE,AH
  172.  
  173.                MOV     BX,OFFSET STACK_POINTER + 15
  174.                MOV     CL,4
  175.                SHR     BX,CL
  176.                ADD     BX,PREFIX_P + SUFFIX_P + READ_P + WRITE_P
  177.                MOV     AH,4AH                  ;Allocate memory.
  178.                INT     21H
  179.                JNC     SETUP_STACK
  180.                MOV     DX,OFFSET MEMORY_MSG
  181.                JMP     SHORT ERROR_EXIT              ;If not enough, exit.
  182.  
  183. SETUP_STACK:   MOV     AX,OFFSET STACK_POINTER
  184.                MOV     SP,AX                   ;Set up stack.
  185.                ADD     AX,15
  186.                MOV     CL,4
  187.                SHR     AX,CL
  188.                MOV     CX,DS
  189.                ADD     AX,CX
  190.                ADD     AX,PREFIX_P + SUFFIX_P
  191.                MOV     READ_SEG,AX
  192.                ADD     AX,READ_P
  193.                MOV     WRITE_SEG,AX
  194.  
  195.                CALL    PARSE
  196.                JC      ERROR_EXIT
  197.                MOV     DX,OFFSET ZIP_NAME
  198.                XOR     CX,CX
  199.                MOV     AH,4EH
  200.                INT     21H
  201.                JMP     SHORT DO_EXTRACT
  202.  
  203. NEXT_EXTRACT:  CALL    WRITE_CRLF
  204. NEXT_EXTRACT2: MOV     BX,READ_HANDLE
  205.                MOV     AH,3EH
  206.                INT     21H
  207.  
  208.                PUSH    CS
  209.                POP     ES
  210.                MOV     AH,4FH
  211.                INT     21H
  212.                JNC     DO_EXTRACT
  213.  
  214. GOOD_EXIT:     XOR     AL,AL
  215.                JMP     SHORT EXIT
  216.  
  217. DO_EXTRACT:    MOV     SI,OFFSET DTA.FILE_NAME
  218.                MOV     DI,OFFSET ZIP_NAME
  219.                CALL    FORM_NAME
  220.  
  221.                MOV     DX,OFFSET ZIP_NAME
  222.                MOV     AX,3D00H
  223.                INT     21H
  224.                MOV     DX,OFFSET NOT_FOUND_MSG
  225.                JC      ERROR_EXIT
  226.  
  227.                MOV     READ_HANDLE,AX
  228.                CALL    EXTRACT
  229.                JNC     NEXT_EXTRACT
  230.                CMP     DX,OFFSET ZIP_MSG
  231.                JZ      NEXT_EXTRACT2
  232.  
  233. ERROR_EXIT:    PUSH    DX
  234.                CALL    WRITE_CRLF
  235.                POP     DX
  236.                CALL    PRINT_STRING
  237.                CALL    WRITE_CRLFLF
  238.                MOV     DX,OFFSET COPYRIGHT
  239.                CALL    PRINT_STRING
  240.                MOV     AL,1
  241.  
  242. EXIT:          MOV     AH,4CH
  243.                INT     21H
  244.  
  245. MAIN           ENDP
  246.  
  247. ;**************
  248. ; SUBROUTINES *
  249. ;**************
  250.  
  251. ;OUTPUT: CF=1 if parse fail.
  252.  
  253. PARSE:         MOV     SEARCH_LEN,ZIP_LEN
  254.                MOV     SEARCH_NAME,OFFSET ZIP_NAME
  255.                MOV     SI,81H
  256. NEXT_PARSE:    CALL    PARSE_DELIMIT
  257.                LODSB
  258.                CMP     AL,CR
  259.                JZ      PARSE_DONE
  260.                CMP     AL,"-"
  261.                JZ      SWITCH
  262.                CMP     AL,"/"
  263.                JNZ     DO_FILENAME
  264. SWITCH:        CALL    PARSE_SWITCH
  265.                JC      PARSE_END
  266.                JMP     NEXT_PARSE
  267.  
  268. DO_FILENAME:   DEC     SI
  269.                MOV     CX,SEARCH_LEN
  270.                MOV     DI,SEARCH_NAME
  271.                CALL    STORE_SEARCH
  272.                MOV     SEARCH_LEN,DIR_LEN
  273.                MOV     SEARCH_NAME,OFFSET DIR_NAME
  274.                JMP     NEXT_PARSE
  275.  
  276.  
  277. PARSE_DONE:    MOV     DX,OFFSET SYNTAX_MSG
  278.                CMP     BYTE PTR ZIP_NAME,0
  279.                STC
  280.                JZ      PARSE_END
  281.  
  282.                MOV     DX,OFFSET ZIP_NAME
  283.                XOR     CX,CX
  284.                MOV     AH,4EH
  285.                INT     21H
  286.                JNC     FOUND_ZIP
  287.                CALL    TACK_ZIP
  288.                MOV     DX,OFFSET ZIP_NAME
  289.                XOR     CX,CX
  290.                MOV     AH,4EH
  291.                INT     21H
  292.                MOV     DX,OFFSET NOT_FOUND_MSG
  293.                JC      PARSE_END
  294.  
  295. FOUND_ZIP:     CMP     DIR_NAME,0
  296.                JZ      PARSE_END
  297.  
  298.                MOV     SI,OFFSET DIR_NAME
  299. NEXT_DIR_END:  LODSB
  300.                OR      AL,AL
  301.                JNZ     NEXT_DIR_END
  302.                DEC     SI
  303.                DEC     SI
  304.                CMP     BYTE PTR [SI],":"
  305.                JZ      PARSE_END
  306.  
  307.                MOV     DX,OFFSET DIR_NAME
  308.                MOV     CX,10H
  309.                MOV     AH,4EH
  310.                INT     21H
  311.                MOV     DX,OFFSET DIR_MSG
  312.                JC      PARSE_END
  313.                TEST    BYTE PTR DS:[DTA.ATTR],10H
  314.                STC
  315.                JZ      PARSE_END
  316.  
  317.                CMP     BYTE PTR [SI],"\"
  318.                JZ      PARSE_END
  319.                MOV     BYTE PTR [SI+1],"\"
  320.                CLC
  321.  
  322. PARSE_END:     RET
  323.  
  324. ;----------------------;
  325.  
  326. PARSE_DELIMIT: LODSB
  327.                CMP     AL,CR
  328.                JZ      DELIMIT_END
  329.                CMP     AL,SPACE
  330.                JBE     PARSE_DELIMIT
  331. DELIMIT_END:   DEC     SI
  332.                RET
  333.  
  334. ;----------------------;
  335.  
  336. PARSE_SWITCH:  CALL    PARSE_DELIMIT
  337.                CMP     AL,CR
  338.                JZ      SWITCH_ERROR
  339.                LODSB
  340.                AND     AL,5FH
  341.                CMP     AL,"V"
  342.                JNZ     CK_O
  343.                MOV     VIEW_FLAG,TRUE
  344.                CALL    PARSE_DELIMIT
  345.                CMP     AL,CR
  346.                JZ      SWITCH_GOOD
  347.                JMP     SHORT DO_SPECIFIC
  348.  
  349. CK_O:          CMP     AL,"O"
  350.                JNZ     CK_E
  351.                MOV     OVERWRITE_FLAG,TRUE
  352.                JMP     SHORT SWITCH_GOOD
  353.  
  354. CK_E:          CMP     AL,"E"
  355.                JNZ     SWITCH_ERROR
  356.                CALL    PARSE_DELIMIT
  357.                CMP     AL,CR
  358.                JZ      SWITCH_ERROR
  359.                MOV     SPECIFIC_FLAG,TRUE
  360.  
  361. DO_SPECIFIC:   MOV     CX,NAME_LEN
  362.                MOV     DI,OFFSET SPECIFIC_NAME
  363.                CALL    STORE_SEARCH
  364.  
  365. SWITCH_GOOD:   CLC
  366.                JMP     SHORT SWITCH_END
  367.  
  368. SWITCH_ERROR:  MOV     DX,OFFSET SYNTAX_MSG
  369.                STC
  370. SWITCH_END:    RET
  371.  
  372. ;----------------------;
  373. ; INPUT: DI-> storage; CX=length.
  374.  
  375. STORE_SEARCH:  LODSB
  376.                CMP     AL,CR
  377.                JZ      STORE_DONE
  378.                CMP     AL,SPACE
  379.                JBE     STORE_END2
  380.                CMP     AL,"a"
  381.                JB      STORE_SEARCH2
  382.                CMP     AL,"z"
  383.                JA      STORE_SEARCH2
  384.                AND     AL,5FH
  385. STORE_SEARCH2: STOSB
  386.                LOOP    STORE_SEARCH
  387.                JMP     SHORT STORE_END2
  388. STORE_DONE:    DEC     SI
  389. STORE_END2:    RET
  390.  
  391. ;----------------------;
  392.  
  393. TACK_ZIP:      MOV     SI,OFFSET ZIP_NAME
  394.                MOV     CX,ZIP_LEN - 4
  395. NEXT_TACK:     LODSB
  396.                CMP     AL,"."
  397.                JZ      TACK_IT
  398.                CMP     AL,0
  399.                JZ      TACK_IT
  400.                LOOP    NEXT_TACK
  401.                JMP     SHORT TACK_END
  402.  
  403. TACK_IT:       DEC     SI
  404.                MOV     DI,SI
  405.                MOV     SI,OFFSET ZIP_EXT
  406.                MOV     CX,4
  407.                REP     MOVSB
  408.  
  409. TACK_END:      RET
  410.  
  411. ;----------------------------------------------;
  412. ; INPUT: SI-> name; DI-> storage.
  413.  
  414. FORM_NAME:     PUSH    SI
  415.                MOV     SI,DI
  416.  
  417. NEW_END:       MOV     BX,SI
  418. FIND_END:      LODSB
  419.                CMP     AL,":"
  420.                JZ      NEW_END
  421.                CMP     AL,"\"
  422.                JZ      NEW_END
  423.                OR      AL,AL
  424.                JNZ     FIND_END
  425.  
  426.                POP     SI
  427.                MOV     DI,BX
  428. FORM_NAME2:    LODSB
  429.                STOSB
  430.                OR      AL,AL
  431.                JNZ     FORM_NAME2
  432.                RET
  433.  
  434. ;----------------------------------------------;
  435.  
  436. ;OUTPUT: If CF=1 then DX = failed msg.
  437.  
  438. EXTRACT:       MOV     BYTES_TO_READ[0],SIZE LOCAL_HEADER
  439.                MOV     BYTES_TO_READ[2],0
  440.                CALL    READ_ZIP
  441.                JNC     CK_HEADER
  442.                JMP     FAILED
  443.  
  444. CK_HEADER:     MOV     ES,READ_SEG
  445.                MOV     SI,OFFSET LOCAL_SIG
  446.                XOR     DI,DI
  447.                MOV     CX,4
  448.                REPZ    CMPSB
  449.                JZ      PROCESS
  450.  
  451.                MOV     SI,OFFSET CENTRAL_SIG
  452.                XOR     DI,DI
  453.                MOV     CX,4
  454.                REPZ    CMPSB
  455.                JNZ     PROCESS_ERR
  456.                CLC
  457.                JMP     EXTRACT_END
  458.  
  459. PROCESS_ERR:   MOV     DX,OFFSET ZIP_MSG
  460. PROCESS_ERR2:  JMP     FAILED2
  461.  
  462. PROCESS:       CALL    PROCESS_HEADER
  463.                JNC     PROCESS2
  464.                JMP     FAILED2
  465. PROCESS2:      CALL    READ_ZIP
  466.                JC      LILLY_FAIL
  467.  
  468.                MOV     BYTES_TO_READ[0],AX
  469.                MOV     BYTES_TO_READ[2],BX
  470.                CALL    GET_FILENAME
  471.                JC      EXTRACT
  472.  
  473.                MOV     DX,OFFSET DIR_NAME
  474.                XOR     CX,CX
  475.                MOV     AH,3CH
  476.                INT     21H
  477. LILLY_FAIL:    JC      FAILED
  478.                MOV     WRITE_HANDLE,AX
  479.  
  480.                MOV     RUNNING_CRC_32[0],-1
  481.                MOV     RUNNING_CRC_32[2],-1
  482.  
  483.                CMP     BYTES_TO_READ[0],0
  484.                JNZ     PROCESS3
  485.                CMP     BYTES_TO_READ[2],0
  486.                JZ      PROCESS4
  487.  
  488. PROCESS3:      CALL    READ_ZIP
  489.                JC      FAILED
  490.  
  491.                MOV     SAVE_BYTE,0
  492.                MOV     BITS_LEFT,0
  493.  
  494.                CALL    [EXTRACTOR]
  495.  
  496.                PUSHF
  497.                MOV     AL,SPACE
  498.                CALL    SPIN_IT
  499.                CALL    WRITE_CRLFLF
  500.                POPF
  501.  
  502.                JC      FAILED
  503.                CALL    WRITE
  504.                JC      FAILED
  505.  
  506. PROCESS4:      MOV     BX,WRITE_HANDLE
  507.                MOV     CX,TIME_STAMP
  508.                MOV     DX,DATE_STAMP
  509.                MOV     AX,5701H
  510.                INT     21H
  511.                JC      FAILED
  512.                MOV     AH,3EH
  513.                INT     21H
  514.  
  515.                CALL    CK_CRC
  516.                JC      FAILED
  517.  
  518.                CMP     BYTES_TO_READ[0],0
  519.                JNZ     FAILED
  520.                CMP     BYTES_TO_READ[2],0
  521.                JNZ     FAILED
  522.                MOV     EXTRACTED_FLAG,TRUE
  523.                JMP     EXTRACT
  524.  
  525. FAILED:        MOV     DX,OFFSET FAILED_MSG
  526. FAILED2:       STC
  527.  
  528. EXTRACT_END:   RET
  529.  
  530. ;----------------------------------------------;
  531. ; INPUT:CX=FILENAME_LEN; OUTPUT: CF=1 if skipped.
  532.  
  533. END_FILENAME   DW      ?
  534.  
  535. GET_FILENAME:  MOV     AX,CS
  536.                MOV     ES,AX
  537.                MOV     DI,OFFSET OUTFILE
  538.                PUSH    DS
  539.                MOV     DS,READ_SEG
  540.                XOR     SI,SI
  541.  
  542. NEXT_FILENAME: LODSB
  543.                CMP     AL,"/"
  544.                JNZ     STORE_NAME
  545.                MOV     DI,OFFSET OUTFILE
  546.                JMP     SHORT STORE_NAME2
  547.  
  548. STORE_NAME:    STOSB
  549. STORE_NAME2:   LOOP    NEXT_FILENAME
  550.                MOV     SI,DI
  551.                XOR     AL,AL
  552.                STOSB
  553.                POP     DS
  554.  
  555.                MOV     SI,OFFSET OUTFILE
  556.                MOV     DI,OFFSET DIR_NAME
  557.                CALL    FORM_NAME
  558.                DEC     DI
  559.                MOV     END_FILENAME,DI
  560.  
  561.                CALL    VIEW_OR_SPEC
  562.                JC      FILENAME_END
  563.  
  564.                MOV     DX,OFFSET DIR_NAME
  565.                MOV     AX,3D00H
  566.                INT     21H
  567.                CMC
  568.                JNC     FILENAME_END
  569.  
  570.                MOV     BX,AX
  571.                MOV     AH,3EH
  572.                INT     21H
  573.  
  574.                CMP     OVERWRITE_FLAG,TRUE
  575.                CLC
  576.                JZ      FILENAME_END
  577.  
  578.                CALL    WRITE_FILENAME
  579.                MOV     DX,OFFSET EXISTS_MSG
  580.                CALL    PRINT_STRING
  581.  
  582. CK_KEY:        MOV     AH,1                    ;Is there a keystroke available.
  583.                INT     16H
  584.                JZ      NEXT_KEY
  585. CLEAR_IT:      XOR     AH,AH
  586.                INT     16H
  587.                JMP     CK_KEY
  588.  
  589. NEXT_KEY:      XOR     AH,AH
  590.                INT     16H
  591.                CLC
  592.                CMP     AH,Y_SCAN
  593.                JZ      CONTINUE
  594.                CMP     AL,3                    ;Ctrl break
  595.                JNZ     CK_N
  596.                JMP     GOOD_EXIT
  597. CK_N:          CMP     AH,N_SCAN
  598.                JNZ     NEXT_KEY
  599.  
  600.                MOV     DX,BYTES_TO_READ[0]
  601.                MOV     CX,BYTES_TO_READ[2]
  602.                MOV     BX,READ_HANDLE
  603.                MOV     AX,4201H
  604.                INT     21H
  605.                STC
  606.  
  607. CONTINUE:      PUSHF
  608.                CALL    WRITE_CRLFLF
  609.                POPF
  610.  
  611. FILENAME_END:  RET
  612.  
  613. ;----------------------;
  614. ; OUTPUT: CF=1 of should not be extracted.
  615.  
  616. VIEW_OR_SPEC:  CMP     VIEW_FLAG,TRUE
  617.                JNZ     CK_SPECIFIC
  618.                CMP     SPECIFIC_NAME,0
  619.                JZ      DO_DISPLAY
  620.                CALL    CK_MATCH
  621.                JC      ADVANCE_FILE
  622.  
  623. DO_DISPLAY:    CALL    DISPLAY_NAME
  624.                JMP     SHORT ADVANCE_FILE
  625.  
  626. CK_SPECIFIC:   CMP     SPECIFIC_FLAG,TRUE
  627.                CLC
  628.                JNZ     V_OR_S_END
  629.                CALL    CK_MATCH
  630.                JNC     V_OR_S_END
  631.  
  632. ADVANCE_FILE:  MOV     DX,BYTES_TO_READ[0]
  633.                MOV     CX,BYTES_TO_READ[2]
  634.                MOV     BX,READ_HANDLE
  635.                MOV     AX,4201H
  636.                INT     21H
  637.                JC      V_OR_S_END
  638.                CMC
  639.  
  640. V_OR_S_END:    RET
  641.  
  642. ;----------------------;
  643. ; OUTPUT: CF=1 if no match.
  644.  
  645. CK_MATCH:      MOV     SI,OFFSET SPECIFIC_NAME
  646.                MOV     DI,OFFSET OUTFILE
  647.  
  648. NEXT_NAME:     LODSB
  649.                MOV     AH,[DI]
  650.                CMP     AL,"*"
  651.                JZ      FIND_DOT
  652.  
  653. CK_Q:          CMP     AL,"?"
  654.                JNZ     COMPARE_NAME
  655.                OR      AH,AH
  656.                JZ      NEXT_NAME
  657.                CMP     AH,"."
  658.                JZ      NEXT_NAME
  659.                INC     DI
  660.                JMP     NEXT_NAME
  661.  
  662. COMPARE_NAME:  INC     DI
  663.                CMP     AL,AH
  664.                JNZ     NO_MATCH
  665.                OR      AL,AL
  666.                JZ      MATCH
  667.                CMP     AL,"."
  668.                JNZ     NEXT_NAME
  669.                JMP     SHORT NEXT_EXT
  670.  
  671. FIND_DOT:      LODSB
  672.                CMP     AL,"."
  673.                JZ      DO_OUTFILE
  674.                OR      AL,AL
  675.                JNZ     FIND_DOT
  676.                DEC     SI
  677.  
  678. DO_OUTFILE:    MOV     AL,[DI]
  679.                OR      AL,AL
  680.                JZ      NEXT_EXT
  681.                INC     DI
  682.                CMP     AL,"."
  683.                JNZ     DO_OUTFILE
  684.  
  685. NEXT_EXT:      LODSB
  686.                MOV     AH,[DI]
  687.                CMP     AL,"*"
  688.                JZ      MATCH
  689.                CMP     AL,"?"
  690.                JNZ     COMPARE_EXT
  691.                OR      AH,AH
  692.                JZ      NEXT_EXT
  693.                INC     DI
  694.                JMP     NEXT_EXT
  695.  
  696. COMPARE_EXT:   INC     DI
  697.                CMP     AL,AH
  698.                JNZ     NO_MATCH
  699.                OR      AL,AL
  700.                JNZ     NEXT_EXT
  701.  
  702. MATCH:         CLC
  703.                JMP     SHORT CK_MATCH_END
  704.  
  705. NO_MATCH:      STC
  706.  
  707. CK_MATCH_END:  RET
  708.  
  709. ;----------------------;
  710.  
  711. DISPLAY_NAME:  MOV     EXTRACTED_FLAG,TRUE
  712.  
  713.                MOV     DI,OFFSET VIEW_NAME
  714.                MOV     AL,SPACE
  715.                MOV     CX,SIZE VIEW_NAME
  716.                REP     STOSB
  717.  
  718.                MOV     SI,OFFSET OUTFILE       ;Point to filename.
  719.                MOV     DI,OFFSET VIEW_NAME
  720.                MOV     CX,NAME_LEN             ;Store 12 bytes of filename.
  721.                JMP     SHORT NEXT_STORE2
  722.  
  723. EXTENSION:     ADD     DI,CX
  724.                MOV     CX,3
  725.                SUB     DI,CX
  726.  
  727. NEXT_STORE2:   LODSB                           ;Get a byte.
  728.                OR      AL,AL                   ;End of filename?
  729.                JZ      END_STORE               ;If yes, finish with blanks.
  730.                CMP     AL,"."                  ;Is it the period?
  731.                JZ      EXTENSION
  732.  
  733.                STOSB                           ;Store byte.
  734.                LOOP    NEXT_STORE2             ;Get next byte.
  735. END_STORE:     ADD     DI,CX
  736.  
  737. STORE_SIZE:    PUSH    DI                      ;Save pointer.
  738.                ADD     DI,8                    ;Move to end of bytes field.
  739.                MOV     DX,SIZE_LOW             ;Retrieve high and low words
  740.                MOV     AX,SIZE_HIGH            ; of size in bytes.
  741.                MOV     BX,10
  742.                STD                             ;Reverse direction.
  743. NEXT_SIZE:     MOV     CX,DX                   ;Low word in CX.
  744.                XOR     DX,DX                   ;Zero in high half.
  745.                DIV     BX                      ;Convert to decimal.
  746.                XCHG    AX,CX                   ;Retrieve low word.
  747.                DIV     BX
  748.                XCHG    AX,DX                   ;Retrieve remainder.
  749.                ADD     AL,"0"                  ;Convert to ASCII.
  750.                STOSB                           ;Store it.
  751.                MOV     AX,CX                   ;Are we done?
  752.                OR      CX,DX
  753.                JNZ     NEXT_SIZE               ;If no, divide again.
  754.  
  755.                CLD                             ;Back to forward direction.
  756.                POP     DI                      ;Retrieve pointer.
  757.                ADD     DI,11                   ;Move to date field.
  758.  
  759. STORE_DATE:    MOV     DX,DATE_STAMP           ;Retrieve date.
  760.                MOV     AX,DX
  761.                MOV     CL,5                    ;Shift to lowest bits.
  762.                SHR     AX,CL
  763.                AND     AX,1111B                ;Mask off all but month.
  764.                MOV     CL,0FFH                 ;Flag as no leading zeros.
  765.                MOV     CH,"-"                  ;Delimiting character.
  766.                CALL    STORE_WORD              ;Store it.
  767.  
  768.                MOV     AX,DX                   ;Retrieve date.
  769.                AND     AX,11111B               ;Mask off all but day.
  770.                XOR     CL,CL                   ;Flag include leading zeros.
  771.                CALL    STORE_WORD              ;Store it.
  772.  
  773.                MOV     AX,DX                   ;Retrieve date for last time.
  774.                MOV     CL,9
  775.                SHR     AX,CL                   ;Mask off all but year.
  776.                ADD     AX,80                   ;Adjust to ASCII.
  777.                CMP     AX,100                  ;Past year 2000?
  778.                JB      DISPLAY_DATE            ;If no, display. Else, adjust for
  779.                SUB     AX,100                  ; next century. (Planning ahead!)
  780. DISPLAY_DATE:  XOR     CL,CL                   ;Display leading zeros.
  781.                MOV     CH,SPACE
  782.                CALL    STORE_WORD              ;Store it.
  783.  
  784. TIME:          INC     DI                      ;Move to time field.
  785.                MOV     DX,TIME_STAMP           ;Retrieve time.
  786.                MOV     AX,DX
  787.                MOV     CL,11                   ;Shift to hours bits.
  788.                SHR     AX,CL
  789.                PUSH    AX
  790.                CMP     AX,12                   ;Past noon?
  791.                JBE     MERIDIAN
  792.                SUB     AX,12                   ;If yes, adjust.
  793. MERIDIAN:      CMP     AX,0                    ;Midnight?
  794.                JNZ     NOT_MIDNIGHT
  795.                MOV     AX,12                   ;If yes, adjust.
  796. NOT_MIDNIGHT:  MOV     CL,0FFH                 ;Suppress leading zeros.
  797.                MOV     CH,":"
  798.                CALL    STORE_WORD              ;Store it.
  799.  
  800.                MOV     AX,DX                   ;Retrieve time.
  801.                MOV     CL,5                    ;Shift to minutes bits.
  802.                SHR     AX,CL
  803.                AND     AX,111111B              ;Mask off all but minutes.
  804.                XOR     CL,CL
  805.                POP     DX                      ;Retrieve hours.
  806.                MOV     CH,"p"                  ;Assume PM.
  807.                CMP     DX,12                   ;Is it PM?
  808.                JAE     PM
  809.                MOV     CH,"a"                  ;If no, AM.
  810.  
  811. PM:            CALL    STORE_WORD              ;Store it.
  812.                MOV     DX,OFFSET VIEW_NAME
  813.                MOV     AH,9H
  814.                INT     21H
  815.                RET
  816.  
  817. ;-----------------------------------------------------------------------;
  818. ; Converts a two byte hex number to decimal followed by delimiter.      ;
  819. ; INPUT: AX = hex number; BL = 10; CH = delimiter character to store.   ;
  820. ;   CL = 0 if zeros are to be stored; CL = -1 if leading zeros ignored. ;
  821. ;   ES:DI points to storage.                                            ;
  822. ;-----------------------------------------------------------------------;
  823. STORE_WORD:    DIV     BL                      ;Divide by ten.
  824.                ADD     AX,"00"                 ;Convert to ASCII.
  825.                CMP     CL,0                    ;Are we to display leading zero?
  826.                JZ      STORE_IT                ;If yes, store as is.
  827.                CMP     AL,"0"                  ;Is it a leading zero?
  828.                JNZ     STORE_IT                ;If no, store it.
  829.                MOV     AL,SPACE                ;Else, store a space.
  830. STORE_IT:      STOSW
  831.                MOV     AL,CH                   ;Store delimiter character also.
  832.                STOSB
  833.                RET
  834.  
  835. ;----------------------------------------------;
  836. ;OUTPUT: AX=COMPRESS_SIZE[0]; BX=COMPRESS_SIZE[2]; CX=FILENAME_LEN;
  837. ;        CF=1 if failed.
  838.  
  839. COMPRESS_FLAG  DB      ?
  840. TIME_STAMP     DW      ?
  841. DATE_STAMP     DW      ?
  842. FILE_CRC       DW      ?,?
  843. SIZE_HIGH      DW      ?
  844. SIZE_LOW       DW      ?
  845.  
  846. REDUCE_L       DW      ?
  847. REDUCE_F       DW      ?
  848. REDUCE_D1      DB      ?
  849. REDUCE_D2      DW      ?
  850.  
  851. PROCESS_HEADER:PUSH    DS
  852.                MOV     DS,READ_SEG
  853.                MOV     AX,DS:BIT_FLAG
  854.                MOV     CS:COMPRESS_FLAG,AL
  855.                TEST    AX,1
  856.                MOV     DX,OFFSET ENCRYPTED_MSG
  857.                JNZ     PROCESS_FAIL
  858.  
  859.                CALL    PROCESS_TYPE
  860.                MOV     DX,OFFSET UNKNOWN_MSG
  861.                JC      PROCESS_FAIL
  862.  
  863.                XOR     DL,DL
  864.                MOV     AH,36H
  865.                INT     21H
  866.                CMP     AX,0FFFFH
  867.                MOV     DX,OFFSET INVALID_MSG
  868.                JZ      PROCESS_FAIL
  869.                MUL     BX
  870.                MUL     CX
  871.                SUB     AX,DS:UNCOMPRESS_SIZE[0]
  872.                SBB     DX,DS:UNCOMPRESS_SIZE[2]
  873.                MOV     DX,OFFSET DISK_MSG
  874.                JC      PROCESS_FAIL
  875.  
  876.                MOV     AX,DS:UNCOMPRESS_SIZE[0]
  877.                MOV     CS:SIZE_LOW,AX
  878.                MOV     AX,DS:UNCOMPRESS_SIZE[2]
  879.                MOV     CS:SIZE_HIGH,AX
  880.  
  881.                MOV     CX,DS:FILENAME_LEN
  882.                MOV     DX,DS:EXTRA_FIELD_LEN
  883.                ADD     DX,CX
  884.                MOV     AX,DS:COMPRESS_SIZE[0]
  885.                MOV     BX,DS:COMPRESS_SIZE[2]
  886.                MOV     SI,DS:FILE_TIME
  887.                MOV     DI,DS:FILE_DATE
  888.                MOV     BP,DS:CRC_32[0]
  889.                MOV     CS:FILE_CRC[0],BP
  890.                MOV     BP,DS:CRC_32[2]
  891.                CLC
  892.                JMP     SHORT PROCESS_END
  893.  
  894. PROCESS_FAIL:  STC
  895.  
  896. PROCESS_END:   POP     DS
  897.                MOV     FILE_CRC[2],BP
  898.                MOV     BYTES_TO_READ[0],DX
  899.                MOV     TIME_STAMP,SI
  900.                MOV     DATE_STAMP,DI
  901.                RET
  902.  
  903. ;----------------------------------------------;
  904. ; OUTPUT: CF=1 if failed.
  905.  
  906. PROCESS_TYPE:  MOV     BX,DS:ZIP_TYPE
  907.                MOV     AX,OFFSET UNSTORE
  908.                OR      BX,BX
  909.                JZ      STORE_EXTRACT
  910.  
  911.                MOV     AX,OFFSET UNSHRINK
  912.                DEC     BX
  913.                JZ      STORE_EXTRACT
  914.  
  915.                MOV     AX,OFFSET EXPAND
  916.                MOV     DX,7FH
  917.                MOV     CX,701H
  918.                DEC     BX
  919.                JZ      STORE_EXPAND
  920.  
  921.                MOV     DX,3FH
  922.                MOV     CX,603H
  923.                DEC     BX
  924.                JZ      STORE_EXPAND
  925.  
  926.                MOV     DX,1FH
  927.                MOV     CX,507H
  928.                DEC     BX
  929.                JZ      STORE_EXPAND
  930.  
  931.                MOV     DX,0FH
  932.                MOV     CX,40FH
  933.                DEC     BX
  934.                JNZ     CK_EXPLODE
  935.  
  936. STORE_EXPAND:  MOV     CS:REDUCE_L,DX
  937.                MOV     CS:REDUCE_F,DX
  938.                MOV     CS:REDUCE_D1,CH
  939.                XOR     CH,CH
  940.                MOV     CS:REDUCE_D2,CX
  941.                JMP     SHORT STORE_EXTRACT
  942.  
  943. CK_EXPLODE:    MOV     AX,OFFSET EXPLODE
  944.                DEC     BX
  945.                JZ      STORE_EXTRACT
  946.                STC
  947.                JMP     SHORT TYPE_END
  948.  
  949. STORE_EXTRACT: MOV     CS:EXTRACTOR,AX
  950.                CLC
  951. TYPE_END:      RET
  952.  
  953. ;----------------------------------------------;
  954. ; OUTPUT: CF=1 if failed.
  955.  
  956. CK_CRC:        MOV     AX,RUNNING_CRC_32[0]
  957.                MOV     DX,RUNNING_CRC_32[2]
  958.                XOR     AX,0FFFFH
  959.                XOR     DX,0FFFFH
  960.                CMP     AX,FILE_CRC[0]
  961.                STC
  962.                JNZ     CRC_END
  963.                CMP     DX,FILE_CRC[2]
  964.                STC
  965.                JNZ     CRC_END
  966.                CLC
  967. CRC_END:       RET
  968.  
  969. ;**********************************************;
  970.  
  971. ;----------------------------------------------;
  972. ; OUTPUT: CF=1 if failed.
  973.  
  974. ;**********************************************;
  975.  
  976. EXTRACT_MSG    DB      "Extracting $"
  977.  
  978. UNSTORE:       MOV     DX,OFFSET EXTRACT_MSG
  979.                CALL    PRINT_STRING
  980.                CALL    WRITE_FILENAME
  981.  
  982. UNSTORE_SPIN:  CALL    SPINNER
  983.  
  984. NEXT_UNSTORE:  INC     SPIN_CNT
  985.                JZ      UNSTORE_SPIN
  986.  
  987.                MOV     ES,READ_SEG
  988.                MOV     SI,READ_PTR
  989.                CMP     SI,BYTES_READ
  990.                JZ      GET_BYTES2
  991.                MOV     AL,ES:[SI]
  992.                INC     READ_PTR
  993.                CALL    STORE_CHAR
  994.                JNC     NEXT_UNSTORE
  995.                CLC
  996.                JMP     SHORT UNSTORE_END
  997.  
  998. GET_BYTES2:    CALL    READ_ZIP
  999.                JNC     NEXT_UNSTORE
  1000.                CLC
  1001.  
  1002. UNSTORE_END:   RET
  1003.  
  1004. ;----------------------------------------------;
  1005. ; OUTPUT: CF=1 if failed.
  1006.  
  1007. EXPAND_MSG     DB      "Expanding $"
  1008.  
  1009. STATE          DW      ?
  1010. LAST_CHAR      DB      ?
  1011.  
  1012. EXPAND:        MOV     DX,OFFSET EXPLODE_MSG
  1013.                CALL    PRINT_STRING
  1014.                CALL    WRITE_FILENAME
  1015.  
  1016.                MOV     WRITE_FLAG,0
  1017.                MOV     LAST_CHAR,0
  1018.                MOV     STATE,OFFSET STATE_ZERO
  1019.  
  1020.                CALL    LOAD_FOLLOWERS
  1021.                JC      EXPAND_END
  1022.  
  1023. EXPAND_SPIN:   CALL    SPINNER
  1024.  
  1025. NEXT_EXPAND:   INC     SPIN_CNT
  1026.                JZ      EXPAND_SPIN
  1027.  
  1028.                MOV     AX,SIZE FOLLOWER
  1029.                MUL     LAST_CHAR
  1030.                MOV     BP,AX
  1031.  
  1032.                CMP     BYTE PTR FOLLOWERS[BP],0
  1033.                JNZ     GET_BIT
  1034.  
  1035.                MOV     BL,8
  1036.                CALL    GET_CODE
  1037.                JNC     DO_EXPAND
  1038.                JMP     SHORT EXPAND_END
  1039.  
  1040. GET_BIT:       MOV     BL,1
  1041.                CALL    GET_CODE
  1042.                JC      EXPAND_END
  1043.                OR      AL,AL
  1044.                JZ      GET_FOLLOW
  1045.  
  1046.                MOV     BL,8
  1047.                CALL    GET_CODE
  1048.                JNC     DO_EXPAND
  1049.                JMP     SHORT EXPAND_END
  1050.  
  1051. GET_FOLLOW:    MOV     BH,FOLLOWERS[BP]
  1052.                SUB     BH,1
  1053.                JC      EXPAND_ERR
  1054.                MOV     BL,8
  1055.                JMP     SHORT NEXT_BIT2
  1056. NEXT_BIT:      DEC     BL
  1057. NEXT_BIT2:     SHL     BH,1
  1058.                JNC     NEXT_BIT
  1059.                CALL    GET_CODE
  1060.                JC      EXPAND_END
  1061.                MOV     SI,AX
  1062.                INC     SI
  1063.                MOV     AL,FOLLOWERS[BP+SI]
  1064.                XOR     AH,AH
  1065.  
  1066. DO_EXPAND:     MOV     LAST_CHAR,AL
  1067.                CALL    [STATE]
  1068.                JNC     NEXT_EXPAND
  1069. EXPAND_ERR:    STC
  1070.                JMP     SHORT EXPAND_END2
  1071.  
  1072. EXPAND_END:    CLC
  1073. EXPAND_END2:   RET
  1074.  
  1075. ;----------------------------------------------;
  1076. ; OUTPUT: CF=1 if failed.
  1077.  
  1078. LOAD_FOLLOWERS:MOV     BP,255 * SIZE FOLLOWER
  1079. NEXT_FOLLOW:   MOV     BL,6
  1080.                CALL    GET_CODE
  1081.                JC      FOLLOWERS_END
  1082.                MOV     FOLLOWERS[BP],AL
  1083.                OR      AL,AL
  1084.                JZ      LOOP_FOLLOW
  1085.                XOR     DI,DI
  1086.  
  1087. NEXT_FOLLOW2:  MOV     BL,8
  1088.                CALL    GET_CODE
  1089.                JC      FOLLOWERS_END
  1090.                INC     DI
  1091.                MOV     FOLLOWERS[BP+DI],AL
  1092.                MOV     AX,DI
  1093.                CMP     AL,FOLLOWERS[BP]
  1094.                JB      NEXT_FOLLOW2
  1095.  
  1096. LOOP_FOLLOW:   SUB     BP,SIZE FOLLOWER
  1097.                JNC     NEXT_FOLLOW
  1098.                CLC
  1099.  
  1100. FOLLOWERS_END: RET
  1101.  
  1102. ;----------------------------------------------;
  1103. ; INPUT: AL=Char; OUTPUT: CF=1 if failed.
  1104.  
  1105. DLE            =       144
  1106.  
  1107. STATE_ZERO:    CMP     AL,DLE
  1108.                JZ      CHANGE_STATE
  1109.                CALL    STORE_CHAR
  1110.                RET
  1111.  
  1112. CHANGE_STATE:  MOV     STATE,OFFSET STATE_ONE
  1113.                CLC
  1114. ZERO_END:      RET
  1115.  
  1116. ;----------------------------------------------;
  1117. ; INPUT: AL=Char; OUTPUT: CF=1 if failed.
  1118.  
  1119. SAVE_REDUCE    DW      ?
  1120. EXPAND_LEN     DW      ?
  1121.  
  1122. STATE_ONE:     OR      AL,AL
  1123.                JZ      WRITE_DLE
  1124.                MOV     SAVE_REDUCE,AX
  1125.                AND     AX,REDUCE_L
  1126.                MOV     EXPAND_LEN,AX
  1127.                MOV     BX,OFFSET STATE_THREE
  1128.                CMP     AX,REDUCE_F
  1129.                JNZ     SAVE_STATE
  1130.                MOV     BX,OFFSET STATE_TWO
  1131. SAVE_STATE:    MOV     STATE,BX
  1132.                CLC
  1133.                RET
  1134.  
  1135. WRITE_DLE:     MOV     AL,DLE
  1136.                CALL    STORE_CHAR
  1137.                MOV     STATE,OFFSET STATE_ZERO
  1138.                RET
  1139.  
  1140. ;----------------------------------------------;
  1141. ; INPUT: AL=Char; OUTPUT: CF=1 if failed.
  1142.  
  1143. STATE_TWO:     ADD     EXPAND_LEN,AX
  1144.                MOV     STATE,OFFSET STATE_THREE
  1145.                CLC
  1146.                RET
  1147.  
  1148. ;----------------------------------------------;
  1149. ; INPUT: AL=Char; OUTPUT: CF=1 if failed.
  1150.  
  1151. STATE_THREE:   MOV     BX,SAVE_REDUCE
  1152.                MOV     CL,REDUCE_D1
  1153.                SHR     BX,CL
  1154.                AND     BX,REDUCE_D2
  1155.                MOV     CL,8
  1156.                SHL     BX,CL
  1157.                ADD     BX,AX
  1158.                INC     BX
  1159.  
  1160.                MOV     CX,EXPAND_LEN
  1161.                INC     CX
  1162.                INC     CX
  1163.                INC     CX
  1164.                CALL    BACKWARDS
  1165.                MOV     STATE,OFFSET STATE_ZERO
  1166.                RET
  1167.  
  1168. ;**********************************************;
  1169.  
  1170. ;----------------------------------------------;
  1171. ; OUTPUT: CF=1 if failed.
  1172.  
  1173. EXPLODE_MSG    DB      "Exploding $"
  1174.  
  1175. DISTANCE       DW      ?
  1176. DICT_BITS      DB      ?
  1177. MIN_MATCH_LEN  DW      ?
  1178. WRITE_FLAG     DB      ?
  1179.  
  1180. EXPLODE:       MOV     DX,OFFSET EXPLODE_MSG
  1181.                CALL    PRINT_STRING
  1182.                CALL    WRITE_FILENAME
  1183.  
  1184.                MOV     WRITE_FLAG,0
  1185.                CALL    LOAD_TREES
  1186.                JC      LILLY_EXIT4
  1187.  
  1188. EXPLODE_SPIN:  CALL    SPINNER
  1189.  
  1190. NEXT_EXPLODE:  INC     SPIN_CNT
  1191.                JZ      EXPLODE_SPIN
  1192.  
  1193.                MOV     BL,1
  1194.                CALL    GET_CODE
  1195.                JC      LILLY_EXIT3
  1196.                OR      AX,AX
  1197.                JZ      SLIDING_DICT
  1198.                TEST    COMPRESS_FLAG,100B
  1199.                JZ      GET_A_CODE
  1200.                MOV     BP,OFFSET LIT_TREE
  1201.                CALL    READ_TREE
  1202.                JC      LILLY_EXIT3
  1203.                JMP     SHORT STORE_BYTE
  1204.  
  1205. GET_A_CODE:    MOV     BL,8
  1206.                CALL    GET_CODE
  1207.                JC      LILLY_EXIT3
  1208.  
  1209. STORE_BYTE:    CALL    STORE_CHAR
  1210.                JNC     NEXT_EXPLODE
  1211.                JMP     EXPLODE_END2
  1212.  
  1213. LILLY_EXIT3:   CLC
  1214. LILLY_EXIT4:   JMP     EXPLODE_END2
  1215.  
  1216.  
  1217. SLIDING_DICT:  MOV     BL,DICT_BITS
  1218.                CALL    GET_CODE
  1219.                JC      EXPLODE_END2
  1220.                MOV     DISTANCE,AX
  1221.  
  1222.                MOV     BP,OFFSET DISTANCE_TREE
  1223.                CALL    READ_TREE
  1224.                JC      EXPLODE_END2
  1225.                MOV     CL,DICT_BITS
  1226.                SHL     AX,CL
  1227.                OR      DISTANCE,AX
  1228.  
  1229.                MOV     BP,OFFSET LENGTH_TREE
  1230.                CALL    READ_TREE
  1231.                JC      EXPLODE_END2
  1232.                MOV     DI,AX
  1233.                ADD     AX,MIN_MATCH_LEN
  1234.                CMP     DI,63
  1235.                JNZ     DO_BACKWARDS
  1236.                MOV     DI,AX
  1237.                MOV     BL,8
  1238.                CALL    GET_CODE
  1239.                JC      EXPLODE_END
  1240.                ADD     AX,DI
  1241.  
  1242.  
  1243. DO_BACKWARDS:  MOV     CX,AX                   ;Length
  1244.                MOV     BX,DISTANCE
  1245.                INC     BX
  1246.                CALL    BACKWARDS
  1247.                JNC     NEXT_EXPLODE
  1248.                JMP     SHORT EXPLODE_END2
  1249.  
  1250. EXPLODE_END:   CLC
  1251. EXPLODE_END2:  RET
  1252.  
  1253. ;----------------------------------------------;
  1254. ; OUTPUT: CF=1 if failed.
  1255.  
  1256. LOAD_TREES:    MOV     AL,COMPRESS_FLAG
  1257.                MOV     AH,7
  1258.                TEST    AL,10B
  1259.                JNZ     STORE_DICT
  1260.                DEC     AH
  1261. STORE_DICT:    MOV     DICT_BITS,AH
  1262.  
  1263.                MOV     MIN_MATCH_LEN,2
  1264.                TEST    AL,100B
  1265.                JZ      OTHER_TREES
  1266.  
  1267.                MOV     MIN_MATCH_LEN,3
  1268.                MOV     BP,OFFSET LIT_TREE
  1269.                MOV     WORD PTR TREE_ENTRIES[BP],256
  1270.                CALL    LOAD_TREE
  1271.                JC      LOAD_TR_END
  1272.  
  1273. OTHER_TREES:   MOV     BP,OFFSET LENGTH_TREE
  1274.                MOV     WORD PTR TREE_ENTRIES[BP],64
  1275.                CALL    LOAD_TREE
  1276.                JC      LOAD_TR_END
  1277.  
  1278.                MOV     BP,OFFSET DISTANCE_TREE
  1279.                MOV     WORD PTR TREE_ENTRIES[BP],64
  1280.                CALL    LOAD_TREE
  1281.  
  1282. LOAD_TR_END:   RET
  1283.  
  1284. ;----------------------------------------------;
  1285. ; INPUT: BP=Tree index. OUTPUT: CF=1 if failed.
  1286.  
  1287. LOAD_TREE:     CALL    READ_LEN
  1288.                JC      LOAD_TREE_END
  1289.                CALL    SORT_LEN
  1290.                CALL    MAKE_TREE
  1291.                CALL    REVERSE_BITS
  1292.                CLC
  1293. LOAD_TREE_END: RET
  1294.  
  1295. ;----------------------------------------------;
  1296. ; INPUT: BP=Tree index. OUTPUT: CF=1 if failed.
  1297.  
  1298. TREE_BYTES     DB      ?
  1299.  
  1300. READ_LEN:      MOV     BL,8
  1301.                CALL    GET_CODE
  1302.                JC      READ_LEN_END
  1303.                INC     AX
  1304.                MOV     TREE_BYTES,AL
  1305.                XOR     DI,DI
  1306.  
  1307. NEXT_LEN:      MOV     BL,8
  1308.                CALL    GET_CODE
  1309.                JC      READ_LEN_END
  1310.                MOV     AH,AL
  1311.                MOV     CL,4
  1312.                SHR     AH,CL
  1313.                AND     AL,0FH
  1314.                INC     AH
  1315.                INC     AL
  1316.  
  1317. NEXT_LEN2:     MOV     CX,DI
  1318.                MOV     SI,DI
  1319.                SHL     SI,1
  1320.                SHL     SI,1
  1321.                MOV     BIT_LENGTH[BP+SI],AL
  1322.                MOV     VALUE[BP+SI],CL
  1323.                INC     DI
  1324.                DEC     AH
  1325.                JNZ     NEXT_LEN2
  1326.  
  1327.                DEC     TREE_BYTES
  1328.                JNZ     NEXT_LEN
  1329.                CLC
  1330.  
  1331. READ_LEN_END:  RET
  1332.  
  1333. ;----------------------------------------------;
  1334. ; INPUT: BP=Tree index.
  1335.  
  1336. SORT_LEN:      MOV     AX,CS
  1337.                MOV     ES,AX
  1338.                MOV     AX,SIZE SF_TREE
  1339.                MUL     WORD PTR TREE_ENTRIES[BP]
  1340.                ADD     AX,BP
  1341.                MOV     CX,BP
  1342.  
  1343. NEXT_SORT:     MOV     BX,CX
  1344.                MOV     DX,CX
  1345.                ADD     DX,SIZE SF_TREE
  1346.                CMP     DX,AX
  1347.                JAE     SORT_END
  1348.  
  1349. NEXT_SORT2:    MOV     SI,BX
  1350.                MOV     DI,DX
  1351.                CMPSB
  1352.                JB      LOOP_SORT
  1353.                JA      SORT_IT
  1354.  
  1355.                CMPSB
  1356.                JBE     LOOP_SORT
  1357.                DEC     SI
  1358.                DEC     DI
  1359.  
  1360. SORT_IT:       DEC     SI
  1361.                DEC     DI
  1362.                PUSH    [DI]
  1363.                MOVSW
  1364.                POP     [BX]
  1365.  
  1366. LOOP_SORT:     ADD     DX,SIZE SF_TREE
  1367.                CMP     DX,AX
  1368.                JB      NEXT_SORT2
  1369.                ADD     CX,SIZE SF_TREE
  1370.                JMP     NEXT_SORT
  1371.  
  1372. SORT_END:      RET
  1373.  
  1374. ;----------------------------------------------;
  1375. ; INPUT: BP=Tree index.
  1376.  
  1377. MAKE_TREE:     MOV     AX,SIZE SF_TREE
  1378.                MUL     WORD PTR TREE_ENTRIES[BP]
  1379.                ADD     AX,BP
  1380.                MOV     SI,AX
  1381.                XOR     AX,AX                   ;Code
  1382.                XOR     BL,BL                   ;Last bit length
  1383.                XOR     DI,DI                   ;Code increment
  1384.  
  1385. NEXT_MAKE:     SUB     SI,SIZE SF_TREE
  1386.                CMP     SI,BP
  1387.                JB      MAKE_END
  1388.                ADD     AX,DI
  1389.                MOV     TREE_CODE[SI],AX
  1390.                MOV     BH,BIT_LENGTH[SI]
  1391.                CMP     BH,BL
  1392.                JZ      NEXT_MAKE
  1393.  
  1394.                MOV     BL,BH
  1395.                MOV     CL,16
  1396.                SUB     CL,BL
  1397.                MOV     DI,1
  1398.                SHL     DI,CL
  1399.                JMP     NEXT_MAKE
  1400.  
  1401. MAKE_END:      RET
  1402.  
  1403. ;----------------------------------------------;
  1404. ; INPUT: BP=Tree index.
  1405.  
  1406. REVERSE_BITS:  MOV     DX,TREE_ENTRIES[BP]
  1407.                MOV     SI,BP
  1408. NEXT_REV:      INC     SI
  1409.                INC     SI                      ;Code
  1410.                LODSW
  1411.                XOR     BX,BX
  1412.                MOV     CX,16
  1413. NEXT_REV2:     SHR     AX,1
  1414.                RCL     BX,1
  1415.                LOOP    NEXT_REV2
  1416.                MOV     [SI-2],BX
  1417.                DEC     DX
  1418.                JNZ     NEXT_REV
  1419.                RET
  1420.  
  1421. ;----------------------------------------------;
  1422. ; INPUT: BP=Tree index. OUTPUT: AX=code; CF=1 if failed.
  1423.  
  1424. INDEX          DW      ?
  1425. BITS           DB      ?
  1426.  
  1427. READ_TREE:     XOR     DI,DI                   ;Code
  1428.                XOR     DX,DX                   ;Bit length
  1429.                XOR     CL,CL                   ;Bits
  1430. NEXT_READ_T:   MOV     BITS,CL
  1431.                MOV     BL,1
  1432.                CALL    GET_CODE
  1433.                JC      READ_T_END2
  1434.                MOV     CL,BITS
  1435.                SHL     AX,CL
  1436.                OR      DI,AX
  1437.                INC     CL
  1438.                MOV     SI,DX
  1439.  
  1440. NEXT_READ_T2:  SHL     SI,1
  1441.                SHL     SI,1
  1442.                CMP     BIT_LENGTH[BP+SI],CL
  1443.                JA      NEXT_READ_T
  1444.                JZ      NEXT_READ_T3
  1445.                INC     DX
  1446.                MOV     SI,DX
  1447.                CMP     SI,TREE_ENTRIES[BP]
  1448.                JB      NEXT_READ_T2
  1449.                JMP     TREE_ERROR
  1450.  
  1451. NEXT_READ_T3:  CMP     TREE_CODE[BP+SI],DI
  1452.                JNZ     LOOP_TREE
  1453.                MOV     AL,VALUE[BP+SI]
  1454.                XOR     AH,AH
  1455.                JMP     SHORT READ_T_END
  1456.  
  1457. LOOP_TREE:     INC     DX
  1458.                MOV     SI,DX
  1459.                CMP     SI,TREE_ENTRIES[BP]
  1460.                JAE     TREE_ERROR
  1461.                SHL     SI,1
  1462.                SHL     SI,1
  1463.                CMP     BIT_LENGTH[BP+SI],CL
  1464.                JZ      NEXT_READ_T3
  1465.                JMP     NEXT_READ_T
  1466.  
  1467. TREE_ERROR:    STC
  1468.                JMP     SHORT READ_T_END2
  1469.  
  1470. READ_T_END:    CLC
  1471. READ_T_END2:   RET
  1472.  
  1473. ;----------------------------------------------;
  1474. ; INPUT: CX=Length; BX=Distance; OUTPUT: CF=1 if failed.
  1475.  
  1476. BACKWARDS:     MOV     ES,WRITE_SEG
  1477.                MOV     SI,WRITE_PTR
  1478.                SUB     SI,BX
  1479.                JNC     NEXT_BACK
  1480.                CMP     WRITE_FLAG,1
  1481.                JZ      END_BUFF
  1482.  
  1483. NEXT_NULL:     OR      SI,SI
  1484.                JZ      NEXT_BACK
  1485.                XOR     AL,AL
  1486.                CALL    STORE_CHAR
  1487.                JC      BACKWARDS_END
  1488.                INC     SI
  1489.                LOOP    NEXT_NULL
  1490.                JMP     BACKWARDS_END
  1491.  
  1492. END_BUFF:      ADD     SI,WRITE_SIZE
  1493. NEXT_BACK:     MOV     AL,ES:[SI]
  1494.                CALL    STORE_CHAR
  1495.                JC      BACKWARDS_END
  1496.                INC     SI
  1497.                CMP     SI,WRITE_SIZE
  1498.                JNZ     LOOP_BACK
  1499.                XOR     SI,SI
  1500. LOOP_BACK:     LOOP    NEXT_BACK
  1501.                CLC
  1502. BACKWARDS_END: RET
  1503.  
  1504. ;**********************************************;
  1505.  
  1506. ;----------------------------------------------;
  1507. ; OUTPUT: CF=1 if failed.
  1508.  
  1509. BASE_CHAR      DB      ?
  1510. PREV_CODE      DW      ?
  1511. SAVE_CODE      DW      ?
  1512.  
  1513. UNSHRINK_MSG   DB      "Unshrinking $"
  1514.  
  1515. UNSHRINK:      MOV     DX,OFFSET UNSHRINK_MSG
  1516.                CALL    PRINT_STRING
  1517.                CALL    WRITE_FILENAME
  1518.  
  1519.                CALL    INIT_UNSHRINK
  1520.  
  1521.                MOV     BL,CODE_BITS
  1522.                CALL    GET_CODE
  1523.                JC      LILLY_EXIT
  1524.                MOV     PREV_CODE,AX
  1525.                MOV     BASE_CHAR,AL
  1526.                CALL    STORE_CHAR
  1527.                JC      LILLY_EXIT2
  1528.  
  1529. UNSHRINK_SPIN: CALL    SPINNER
  1530.  
  1531. NEXT_UNSHRINK: INC     SPIN_CNT
  1532.                JZ      UNSHRINK_SPIN
  1533.  
  1534.                MOV     BL,CODE_BITS
  1535.                CALL    GET_CODE
  1536.                JC      LILLY_EXIT
  1537.                MOV     SAVE_CODE,AX
  1538.                XOR     CX,CX                   ;String counter.
  1539.  
  1540.                CMP     AX,SPECIAL_CODE
  1541.                JB      STORE_UNSHRUNK
  1542.                JA      CK_ERROR
  1543.  
  1544.                MOV     BL,CODE_BITS
  1545.                CALL    GET_CODE
  1546.                JC      LILLY_EXIT
  1547.                DEC     AX
  1548.                JNZ     CK_CLEAR
  1549.                INC     CODE_BITS
  1550.                JMP     NEXT_UNSHRINK
  1551.  
  1552. CK_CLEAR:      DEC     AX
  1553.                STC
  1554.                JNZ     LILLY_EXIT2
  1555.                CALL    CLEAR
  1556.                JMP     NEXT_UNSHRINK
  1557.  
  1558. LILLY_EXIT:    CLC
  1559. LILLY_EXIT2:   JMP     UNSHRINK_END
  1560.  
  1561. CK_ERROR:      CMP     AX,TRIE_SIZE
  1562.                JA      ERROR
  1563.  
  1564.                MOV     BX,AX
  1565.                SHL     BX,1
  1566.                CMP     WORD PTR PREFIX[BX],FREE
  1567.                JNZ     FIND_STRING2
  1568.                PUSH    WORD PTR BASE_CHAR
  1569.                INC     CX
  1570.  
  1571.                MOV     BX,PREV_CODE
  1572.                CMP     BX,FIRST_FREE
  1573.                JB      GOT_UNSHRUNK
  1574.  
  1575. FIND_STRING:   SHL     BX,1
  1576. FIND_STRING2:  PUSH    SUFFIX[BX]
  1577.                INC     CX
  1578.                MOV     BX,PREFIX[BX]
  1579.                CMP     BX,FIRST_FREE
  1580.                JAE     FIND_STRING
  1581.  
  1582. GOT_UNSHRUNK:  MOV     AL,BL
  1583. STORE_UNSHRUNK:MOV     BASE_CHAR,AL
  1584.  
  1585.                CALL    STORE_CHAR
  1586.                JC      UNSHRINK_END
  1587.                JCXZ    ADD_CODE
  1588. NEXT_STORE:    POP     AX
  1589.                CALL    STORE_CHAR
  1590.                JC      UNSHRINK_END
  1591.                LOOP    NEXT_STORE
  1592.  
  1593. ADD_CODE:      MOV     DI,FREE_NODE
  1594.                MOV     AL,BASE_CHAR
  1595.                MOV     SUFFIX[DI],AL
  1596.                MOV     AX,PREV_CODE
  1597.                MOV     PREFIX[DI],AX
  1598.  
  1599. NEXT_FREE:     INC     DI
  1600.                INC     DI
  1601.                CMP     DI,TRIE_SIZE * 2
  1602.                JA      ERROR
  1603.                CMP     WORD PTR PREFIX[DI],FREE
  1604.                JNZ     NEXT_FREE
  1605.                MOV     FREE_NODE,DI
  1606.  
  1607.                MOV     AX,SAVE_CODE
  1608.                MOV     PREV_CODE,AX
  1609.                JMP     NEXT_UNSHRINK
  1610.  
  1611. ERROR:         STC
  1612.  
  1613. UNSHRINK_END:  RET
  1614.  
  1615. ;----------------------------------------------;
  1616. INIT_UNSHRINK: PUSH    CS
  1617.                POP     ES
  1618.                MOV     DI,OFFSET PREFIX
  1619.                MOV     AX,FREE
  1620.                MOV     CX,TRIE_SIZE
  1621.                REP     STOSW
  1622.  
  1623.                MOV     FREE_NODE,FIRST_FREE * 2
  1624.                MOV     CODE_BITS,MIN_CODE_SIZE
  1625.                RET
  1626.  
  1627. ;----------------------------------------------;
  1628. ; INPUT: BITS_LEFT; BL=CODE_BITS; OUTPUT: AX=code; CF=1 if EOF or failed.
  1629.  
  1630. GET_CODE:      MOV     CL,BL
  1631.                XOR     AX,AX
  1632.                MOV     BH,BITS_LEFT
  1633.                OR      BH,BH
  1634.                JZ      GET_BITS
  1635.                MOV     CH,SAVE_BYTE
  1636.  
  1637. NEXT_SHIFT2:   SHR     CH,1
  1638.                RCR     AX,1
  1639.                DEC     BL
  1640.                JZ      GOT_CODE
  1641.                DEC     BH
  1642.                JNZ     NEXT_SHIFT2
  1643.  
  1644. GET_BITS:      MOV     SI,READ_PTR
  1645.                CMP     SI,BYTES_READ
  1646.                JZ      GET_BYTE
  1647.                MOV     ES,READ_SEG
  1648.                MOV     CH,ES:[SI]
  1649.                INC     READ_PTR
  1650.                MOV     BH,8
  1651.                JMP     NEXT_SHIFT2
  1652.  
  1653. GET_BYTE:      CALL    READ_ZIP
  1654.                JNC     GET_BITS
  1655.                JMP     SHORT GET_CODE_END
  1656.  
  1657. GOT_CODE:      DEC     BH
  1658.                MOV     SAVE_BYTE,CH
  1659.                MOV     BITS_LEFT,BH
  1660.                NEG     CL
  1661.                ADD     CL,16
  1662.                SHR     AX,CL
  1663.                CLC
  1664. GET_CODE_END:  RET
  1665.  
  1666. ;----------------------------------------------;
  1667. CLEAR:
  1668. ;Mark all nodes as potentially unused.
  1669.                MOV     DX,FREE_NODE
  1670.                MOV     AX,8000H
  1671.                MOV     CX,FIRST_FREE * 2
  1672.                MOV     SI,CX
  1673. NEXT_MARK:     CMP     SI,DX
  1674.                JZ      CK_REF
  1675.                OR      PREFIX[SI],AX
  1676.                INC     SI
  1677.                INC     SI
  1678.                JMP     NEXT_MARK
  1679.  
  1680. ;Unmark those that are used by other nodes
  1681. CK_REF:        MOV     SI,CX
  1682. NEXT_REF:      CMP     SI,DX
  1683.                JZ      DO_CLEAR
  1684.                MOV     AX,PREFIX[SI]
  1685.                INC     SI
  1686.                INC     SI
  1687.                AND     AX,7FFFH
  1688.                CMP     AX,FIRST_FREE
  1689.                JB      NEXT_REF
  1690.                MOV     DI,AX
  1691.                SHL     DI,1
  1692.                AND     PREFIX[DI],7FFFH
  1693.                JMP     NEXT_REF
  1694.  
  1695. ;Clear the ones that are still marked
  1696. DO_CLEAR:      MOV     SI,CX
  1697.                MOV     AX,FREE
  1698.                JMP     SHORT NEXT_CLEAR2
  1699. NEXT_CLEAR:    INC     SI
  1700.                INC     SI
  1701. NEXT_CLEAR2:   CMP     SI,DX
  1702.                JZ      FIND_FREE
  1703.                MOV     DI,PREFIX[SI]
  1704.                AND     DI,8000H
  1705.                JZ      NEXT_CLEAR
  1706.                MOV     PREFIX[SI],AX
  1707.                JMP     NEXT_CLEAR
  1708.  
  1709. ;Find first free node
  1710. FIND_FREE:     MOV     SI,FIRST_FREE * 2
  1711.                JMP     SHORT NEXT_FREE3
  1712. NEXT_FREE2:    INC     SI
  1713.                INC     SI
  1714. NEXT_FREE3:    CMP     PREFIX[SI],AX
  1715.                JNZ     NEXT_FREE2
  1716.                MOV     FREE_NODE,SI
  1717.  
  1718.                RET
  1719.  
  1720. ;----------------------------------------------;
  1721. ; OUTPUT: CF=1 if failed or EOF.
  1722.  
  1723. BYTES_TO_READ  DW      ?,?
  1724. READ_PTR       DW      ?
  1725. BYTES_READ     DW      ?
  1726. READ_HANDLE    DW      ?
  1727.  
  1728. READ_ZIP:      PUSH    AX
  1729.                PUSH    BX
  1730.                PUSH    CX
  1731.                PUSH    DX
  1732.                MOV     READ_PTR,0
  1733.  
  1734.                MOV     CX,READ_SIZE
  1735.                CMP     BYTES_TO_READ[2],0
  1736.                JNZ     READ_IT
  1737.                MOV     AX,BYTES_TO_READ[0]
  1738.                OR      AX,AX
  1739.                STC
  1740.                JZ      READ_ZIP_END
  1741.                CMP     CX,AX
  1742.                JBE     READ_IT
  1743.                MOV     CX,AX
  1744.  
  1745. READ_IT:       PUSH    DS
  1746.                MOV     BX,READ_HANDLE
  1747.                XOR     DX,DX
  1748.                MOV     DS,READ_SEG
  1749.                MOV     AH,3FH
  1750.                INT     21H
  1751.                POP     DS
  1752.                JC      READ_ZIP_END
  1753.  
  1754.                CMP     AX,CX
  1755.                STC
  1756.                JNZ     READ_ZIP_END
  1757.                MOV     BYTES_READ,AX
  1758.                SUB     BYTES_TO_READ[0],AX
  1759.                SBB     BYTES_TO_READ[2],0
  1760.                CLC
  1761.  
  1762. READ_ZIP_END:  POP     DX
  1763.                POP     CX
  1764.                POP     BX
  1765.                POP     AX
  1766.                RET
  1767.  
  1768. ;----------------------------------------------;
  1769. ; INPUT: AL=Char; OUTPUT: CF=1 if failed.
  1770.  
  1771. WRITE_PTR      DW      ?
  1772.  
  1773. STORE_CHAR:    MOV     ES,WRITE_SEG
  1774.                MOV     DI,WRITE_PTR
  1775.                STOSB
  1776.                INC     WRITE_PTR
  1777.  
  1778.                MOV     BX,RUNNING_CRC_32[0]
  1779.                MOV     DX,RUNNING_CRC_32[2]
  1780.  
  1781.                XOR     AL,BL
  1782.                XOR     AH,AH
  1783.                MOV     BP,AX
  1784.                SHL     BP,1
  1785.                SHL     BP,1
  1786.  
  1787.                MOV     AL,8
  1788. NEXT_SHIFT:    SAR     DX,1                    ;DX:BX
  1789.                RCR     BX,1
  1790.                DEC     AL
  1791.                JNZ     NEXT_SHIFT
  1792.                AND     DX,00FFH
  1793.  
  1794.                XOR     BX,WORD PTR CRC_32_TABLE[BP]
  1795.                XOR     DX,WORD PTR CRC_32_TABLE[BP+2]
  1796.  
  1797.                MOV     RUNNING_CRC_32[0],BX
  1798.                MOV     RUNNING_CRC_32[2],DX
  1799.  
  1800.                CMP     DI,WRITE_SIZE
  1801.                CLC
  1802.                JNZ     STORE_END
  1803.                CALL    WRITE
  1804. STORE_END:     RET
  1805.  
  1806. ;----------------------------------------------;
  1807. ; OUTPUT: CF=1 if failed.
  1808.  
  1809. WRITE_HANDLE   DW      ?
  1810.  
  1811. WRITE:         PUSH    CX
  1812.                MOV     CX,WRITE_PTR
  1813.                OR      CX,CX
  1814.                JZ      WRITE_END
  1815.                MOV     BX,WRITE_HANDLE
  1816.                XOR     DX,DX
  1817.                PUSH    DS
  1818.                MOV     DS,WRITE_SEG
  1819.                MOV     AH,40H
  1820.                INT     21H
  1821.                POP     DS
  1822.                MOV     WRITE_PTR,0
  1823.                MOV     WRITE_FLAG,1
  1824.  
  1825. WRITE_END:     POP     CX
  1826.                RET
  1827.  
  1828. ;----------------------------------------------;
  1829. WRITE_FILENAME:MOV     DX,OFFSET DIR_NAME
  1830.                MOV     SI,END_FILENAME
  1831.                PUSH    [SI]
  1832.                MOV     BYTE PTR [SI],"$"
  1833.                CALL    PRINT_STRING
  1834.                POP     [SI]
  1835.  
  1836.                MOV     DL,SPACE
  1837.                MOV     AH,2
  1838.                INT     21H
  1839.                RET
  1840.  
  1841. ;----------------------------------------------;
  1842. WRITE_CRLF:    MOV     DX,OFFSET CR_LF
  1843.                JMP     SHORT NEW_LINE
  1844.  
  1845. WRITE_CRLFLF:  MOV     DX,OFFSET CR_LF_LF
  1846. NEW_LINE:      CALL    PRINT_STRING
  1847.                RET
  1848.  
  1849. ;----------------------------------------------;
  1850. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  1851.                INT     21H
  1852.                RET
  1853.  
  1854. ;----------------------------------------------;
  1855. SPINNER:       MOV     SI,SPIN_INDEX
  1856.                SUB     SI,1
  1857.                JNC     STORE_SPIN
  1858.                MOV     SI,2
  1859. STORE_SPIN:    MOV     SPIN_INDEX,SI
  1860.                MOV     AL,SPINNERS[SI]
  1861.  
  1862. SPIN_IT:       XOR     BH,BH
  1863.                MOV     CX,1
  1864.                MOV     BL,ATTRIBUTE
  1865.                MOV     AH,9
  1866.                INT     10H
  1867.                RET
  1868.  
  1869. ;----------------------------------------------;
  1870.  
  1871. CRC_32_TABLE   LABEL DWORD
  1872. DD 000000000h, 077073096h, 0EE0E612Ch, 0990951BAh, 0076DC419h, 0706AF48Fh, 0E963A535h, 09E6495A3h
  1873. DD 00EDB8832h, 079DCB8A4h, 0E0D5E91Eh, 097D2D988h, 009B64C2Bh, 07EB17CBDh, 0E7B82D07h, 090BF1D91h
  1874. DD 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh, 01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h
  1875. DD 0136C9856h, 0646BA8C0h, 0FD62F97Ah, 08A65C9ECh, 014015C4Fh, 063066CD9h, 0FA0F3D63h, 08D080DF5h
  1876. DD 03B6E20C8h, 04C69105Eh, 0D56041E4h, 0A2677172h, 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh
  1877. DD 035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h, 032D86CE3h, 045DF5C75h, 0DCD60DCFh, 0ABD13D59h
  1878. DD 026D930ACh, 051DE003Ah, 0C8D75180h, 0BFD06116h, 021B4F4B5h, 056B3C423h, 0CFBA9599h, 0B8BDA50Fh
  1879. DD 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h, 02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh
  1880. DD 076DC4190h, 001DB7106h, 098D220BCh, 0EFD5102Ah, 071B18589h, 006B6B51Fh, 09FBFE4A5h, 0E8B8D433h
  1881. DD 07807C9A2h, 00F00F934h, 09609A88Eh, 0E10E9818h, 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h
  1882. DD 06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh, 06C0695EDh, 01B01A57Bh, 08208F4C1h, 0F50FC457h
  1883. DD 065B0D9C6h, 012B7E950h, 08BBEB8EAh, 0FCB9887Ch, 062DD1DDFh, 015DA2D49h, 08CD37CF3h, 0FBD44C65h
  1884. DD 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h, 04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh
  1885. DD 04369E96Ah, 0346ED9FCh, 0AD678846h, 0DA60B8D0h, 044042D73h, 033031DE5h, 0AA0A4C5Fh, 0DD0D7CC9h
  1886. DD 05005713Ch, 0270241AAh, 0BE0B1010h, 0C90C2086h, 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh
  1887. DD 05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h, 059B33D17h, 02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh
  1888. DD 0EDB88320h, 09ABFB3B6h, 003B6E20Ch, 074B1D29Ah, 0EAD54739h, 09DD277AFh, 004DB2615h, 073DC1683h
  1889. DD 0E3630B12h, 094643B84h, 00D6D6A3Eh, 07A6A5AA8h, 0E40ECF0Bh, 09309FF9Dh, 00A00AE27h, 07D079EB1h
  1890. DD 0F00F9344h, 08708A3D2h, 01E01F268h, 06906C2FEh, 0F762575Dh, 0806567CBh, 0196C3671h, 06E6B06E7h
  1891. DD 0FED41B76h, 089D32BE0h, 010DA7A5Ah, 067DD4ACCh, 0F9B9DF6Fh, 08EBEEFF9h, 017B7BE43h, 060B08ED5h
  1892. DD 0D6D6A3E8h, 0A1D1937Eh, 038D8C2C4h, 04FDFF252h, 0D1BB67F1h, 0A6BC5767h, 03FB506DDh, 048B2364Bh
  1893. DD 0D80D2BDAh, 0AF0A1B4Ch, 036034AF6h, 041047A60h, 0DF60EFC3h, 0A867DF55h, 0316E8EEFh, 04669BE79h
  1894. DD 0CB61B38Ch, 0BC66831Ah, 0256FD2A0h, 05268E236h, 0CC0C7795h, 0BB0B4703h, 0220216B9h, 05505262Fh
  1895. DD 0C5BA3BBEh, 0B2BD0B28h, 02BB45A92h, 05CB36A04h, 0C2D7FFA7h, 0B5D0CF31h, 02CD99E8Bh, 05BDEAE1Dh
  1896. DD 09B64C2B0h, 0EC63F226h, 0756AA39Ch, 0026D930Ah, 09C0906A9h, 0EB0E363Fh, 072076785h, 005005713h
  1897. DD 095BF4A82h, 0E2B87A14h, 07BB12BAEh, 00CB61B38h, 092D28E9Bh, 0E5D5BE0Dh, 07CDCEFB7h, 00BDBDF21h
  1898. DD 086D3D2D4h, 0F1D4E242h, 068DDB3F8h, 01FDA836Eh, 081BE16CDh, 0F6B9265Bh, 06FB077E1h, 018B74777h
  1899. DD 088085AE6h, 0FF0F6A70h, 066063BCAh, 011010B5Ch, 08F659EFFh, 0F862AE69h, 0616BFFD3h, 0166CCF45h
  1900. DD 0A00AE278h, 0D70DD2EEh, 04E048354h, 03903B3C2h, 0A7672661h, 0D06016F7h, 04969474Dh, 03E6E77DBh
  1901. DD 0AED16A4Ah, 0D9D65ADCh, 040DF0B66h, 037D83BF0h, 0A9BCAE53h, 0DEBB9EC5h, 047B2CF7Fh, 030B5FFE9h
  1902. DD 0BDBDF21Ch, 0CABAC28Ah, 053B39330h, 024B4A3A6h, 0BAD03605h, 0CDD70693h, 054DE5729h, 023D967BFh
  1903. DD 0B3667A2Eh, 0C4614AB8h, 05D681B02h, 02A6F2B94h, 0B40BBE37h, 0C30C8EA1h, 05A05DF1Bh, 02D02EF8Dh
  1904.  
  1905. EVEN
  1906. STACK_POINTER  =  $ + LOCAL_STACK + (TRIE_SIZE * 2)
  1907. PREFIX         =  OFFSET STACK_POINTER
  1908. SUFFIX         =  OFFSET PREFIX + PREFIX_SIZE
  1909.  
  1910. LENGTH_TREE    =  OFFSET STACK_POINTER + 2
  1911. DISTANCE_TREE  =  OFFSET LENGTH_TREE + LEN_TREE_SIZE + 2
  1912. LIT_TREE       =  OFFSET DISTANCE_TREE + DIST_TREE_SIZE + 2
  1913.  
  1914. FOLLOWERS      =  OFFSET STACK_POINTER
  1915.  
  1916. _TEXT          ENDS
  1917.                END     START
  1918.